package com.dataseek.iot.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
//import com.dataseek.iot.mqtt.service.ISendMessage;
import com.dataseek.iot.sys.entity.NotifyLog1;
import com.dataseek.iot.sys.entity.NotifyRule1;
import com.dataseek.iot.sys.entity.NotifyTemplate1;
import com.dataseek.iot.sys.mapper.NotifyRuleMapper1;
import com.dataseek.iot.sys.mapper.NotifyTemplateMapper1;
import com.dataseek.iot.sys.mapper.SysUserMapper1;
import com.dataseek.iot.sys.service.NotifyLogService;
import com.dataseek.iot.sys.service.NotifyRuleService;
import com.dataseek.iot.sys.vo.NotifyRuleVo;
import com.dataseek.iot.toolkit.auth.entity.SysUser;
import com.dataseek.iot.toolkit.tenant.config.DynamicDataSourceContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


@Service
@Slf4j
public class NotifyRuleServiceImpl extends ServiceImpl<NotifyRuleMapper1, NotifyRule1> implements NotifyRuleService {


    @Autowired
    private NotifyRuleMapper1 notifyRuleMapper1;

    @Autowired
    private NotifyTemplateMapper1 notifyTemplateMapper1;

    @Autowired
    private SysUserMapper1 sysUserMapper1;

    @Autowired
    private NotifyLogService notifyLogService;

//    @Autowired
//    private ISendMessage iMqttSender;

    @Override
    public NotifyRuleVo queryAction(String notifyName, String notifyCode, String alarmType, Integer num, Integer size) {

        NotifyRuleVo ruleVo = new NotifyRuleVo();
        QueryWrapper<NotifyRule1> qw = new QueryWrapper<>();
        if (notifyName != null && !notifyName.isEmpty()) {
            qw.like("notify_name", notifyName);
        }
        if (notifyCode != null && !notifyCode.isEmpty()) {
            qw.like("notify_code", notifyCode);
        }
        if (alarmType != null && !alarmType.isEmpty()) {
            qw.like("alarm_type", alarmType);
        }
        IPage<NotifyRule1> page = new Page<>(num, size);
        List<NotifyRule1> mapList = notifyRuleMapper1.selectPage(page, qw).getRecords();
        ruleVo.setPage(num);
        ruleVo.setSize(size);
        ruleVo.setTotal(page.getTotal());
        ruleVo.setList(mapList);
        return ruleVo;
    }

    @Override
    public String insertAction(NotifyRule1 notifyRule1) {
        String tenantCode = DynamicDataSourceContextHolder.getDataSourceKey();
        QueryWrapper<NotifyRule1> qw = new QueryWrapper<>();
        qw.eq("notify_name", notifyRule1.getNotifyName()).or().eq("notify_code", notifyRule1.getNotifyCode());
        Integer count = notifyRuleMapper1.selectCount(qw);
        if (count != 0) {
            return "999";
        }

        if (notifyRule1.getCreateBy() == null) {
            if (tenantCode != null && !tenantCode.isEmpty()) {
                notifyRule1.setCreateBy(tenantCode);
                notifyRule1.setUpdateBy(tenantCode);
            }
            else {
                notifyRule1.setCreateBy("");
                notifyRule1.setUpdateBy("");
            }
        }
        this.saveOrUpdate(notifyRule1);
        return "";
    }

    @Override
    public String updateAction(NotifyRule1 notifyRule1) {
        notifyRuleMapper1.updateById(notifyRule1);
        return "";
    }

    @Override
    public Integer deleteAction(List<Integer> ids) {
        int resultCode = notifyRuleMapper1.deleteBatchIds(ids);
        return resultCode;
    }


    public void sendNotifyMsg(String alarmType, Map<String, String> paramMp) {
        //匹配通知规则
        QueryWrapper<NotifyRule1> qw = new QueryWrapper<>();
        qw.eq("alarm_type", alarmType);
        NotifyRule1 matchedRule = this.getOne(qw);
        if (matchedRule != null) {
            //获取通知人信息
            List<SysUser> userList = this.getUserList(matchedRule.getRelaUser());

            //匹配通知模板,发送告警消息
            QueryWrapper<NotifyTemplate1> qwTmp = new QueryWrapper<>();
            qwTmp.eq("template_code", matchedRule.getTemplateCode());
            NotifyTemplate1 matchedTmp = notifyTemplateMapper1.selectOne(qwTmp);
            if (matchedTmp != null) {
                //用参数值替换消息模板
                String notifyMsg = this.createNotifyMsg(matchedTmp.getNotifyText(), paramMp);
                switch (matchedTmp.getNotifyType()) {
                    //系统消息
                    case "A" :
                        for (SysUser tmpUser : userList) {
                            //往前台topic发消息
                            //this.insertNotifyLog(String.valueOf(tmpUser.getUserId()), alarmType, notifyMsg);
//                            iMqttSender.sendToMqtt(String.valueOf(tmpUser.getUserId())+"_"+"alarm", notifyMsg);
                        }
                        break;
                    //邮件
                    case "B" :
                        //参数拼装告警消息
                        notifyMsg = matchedTmp.getNotifyStart() + ", " +  notifyMsg + ", " + matchedTmp.getNotifyEnd();
                        for (SysUser tmpUser : userList) {
                            this.sendEmail(tmpUser.getEmail(), notifyMsg);
                        }
                        break;
                    //短息
                    case "C" :
                        break;
                    default:
                }
            }
        }
    }

    //获取通知人信息
    private List<SysUser> getUserList(String relaUser) {
        List<SysUser> reList = new ArrayList<>();
        String[] userIds = relaUser.split(",");
        for (int i = 0; i < userIds.length; i++) {
            QueryWrapper<SysUser> qwUser = new QueryWrapper<>();
            qwUser.eq("user_id", Integer.parseInt(userIds[i]));
            SysUser tmpUser = sysUserMapper1.selectOne(qwUser);
            if (tmpUser != null) {
                reList.add(tmpUser);
            }
        }
        return  reList;
    }

    private void insertNotifyLog(String userId, String alarmType, String notifyMsg) {
        NotifyLog1 tmpLog = new NotifyLog1();
        tmpLog.setUserId(userId);
        tmpLog.setAlarmType(alarmType);
        tmpLog.setNotifyMsg(notifyMsg);
        tmpLog.setCreateBy("master");
        tmpLog.setUpdateBy("master");
        notifyLogService.insertAction(tmpLog);
    }

    //拼装告警消息
    private String createNotifyMsg(String notifyText, Map<String, String> paramMp) {
        Pattern patten = Pattern.compile("[$][\\{]([^$]*?)[\\}]");
        Matcher matcher = patten.matcher(notifyText);
        while (matcher.find()) {
            String tmpParam = matcher.group(1);
            if (paramMp.containsKey(tmpParam)) {
                notifyText = notifyText.replace("${" + tmpParam + "}", paramMp.get(tmpParam));
            }
        }
        return notifyText;
    }

    private void sendEmail(String toAddress, String emailMsg) {
        try {
            // 创建Properties 类用于记录邮箱的一些属性
            Properties props = new Properties();
            // 表示SMTP发送邮件，必须进行身份验证
            props.put("mail.smtp.auth", "true");
            //此处填写SMTP服务器
            props.put("mail.smtp.host", "smtp.qq.com");
            //端口号，QQ邮箱给出了两个端口，但是另一个我一直使用不了，所以就给出这一个587
            props.put("mail.smtp.port", "587");
            // 此处填写你的账号
            props.put("mail.user", "125863528@qq.com");
            // 此处的密码就是前面说的16位STMP口令
            props.put("mail.password", "bqxcsjplejtbbhje");

            // 构建授权信息，用于进行SMTP进行身份验证
            Authenticator authenticator = new Authenticator() {

                protected PasswordAuthentication getPasswordAuthentication() {
                    // 用户名、密码
                    String userName = props.getProperty("mail.user");
                    String password = props.getProperty("mail.password");
                    return new PasswordAuthentication(userName, password);
                }
            };
            // 使用环境属性和授权信息，创建邮件会话
            Session mailSession = Session.getInstance(props, authenticator);
            // 创建邮件消息
            MimeMessage message = new MimeMessage(mailSession);
            // 设置发件人
            InternetAddress from = new InternetAddress(
                    props.getProperty("mail.user"));
            message.setFrom(from);

            // 设置收件人的邮箱
            InternetAddress to = new InternetAddress(toAddress);
            message.setRecipient(Message.RecipientType.TO, to);

            // 设置邮件标题
            message.setSubject("液位告警通知");

            // 设置邮件的内容体
            message.setContent(emailMsg, "text/html;charset=UTF-8");

            // 最后当然就是发送邮件啦
            Transport.send(message);
        }
        catch (Exception ex) {
            log.info(ex.getLocalizedMessage());
        }

    }

}
